package com.mcx.modules.controller;

import cn.hutool.core.date.DateTime;
import com.mcx.modules.PlayerEntity;
import com.mcx.modules.common.EventDispatcher;
import com.mcx.modules.common.OnActionHandler;
import com.mcx.modules.data.EnumDefine.*;
import com.mcx.modules.data.localdata.create.ShopDBModel;
import com.mcx.modules.data.localdata.create.ShopEntity;
import com.mcx.modules.domain.*;
import com.mcx.modules.entity.Role_BackpackAddItemEntity;
import com.mcx.modules.entity.Role_BackpackItemChangeEntity;
import com.mcx.modules.entity.VirtualItemUpdateEntity;
import com.mcx.modules.proto.*;
import com.mcx.modules.service.*;
import com.mcx.modules.service.dto.*;
import com.mcx.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@Slf4j
@RequiredArgsConstructor
@Component
public class PlayerController {
    private final WorldMapSceneController worldMapSceneController;

    private final PlayerService playerService;
    private final RoleService roleService;
    private final LineupService lineupService;
    private final RoleSkillService roleSkillService;
    private final LogGamelevelService logGamelevelService;
    private final PlayerPassgameleveldetailService playerPassgameleveldetailService;
    private final LogKillmonsterService logKillmonsterService;
    private final GameserverconfigService gameserverconfigService;
    private final LogReceivegoodsService logReceivegoodsService;
    private final PlayerBackpackService playerBackpackService;
    private final PlayerEquipService playerEquipService;
    private final LogShopbuyproductService logShopbuyproductService;

    /**
     * 初始化
     */
    public void Init(){
        //================================================================================系统相关

        //客户端发送本地时间消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.System_SendLocalTime, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnSendLocalTime(player, buffer);
            }
        });

        // ======================================================================================== 登录相关

        //客户端发送登录区服消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.RoleOperation_LoginGameServer, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnLoginGameServer(player, buffer);
            }
        });

        //客户端发送创建角色消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.RoleOperation_CreatePlayer, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnCreatePlayer(player, buffer);
            }
        } );

        //客户端发送进入游戏消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.RoleOperation_EnterGame, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnEnterGame(player, buffer);
            }
        } );

        //客户端发送切换队列角色消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.RoleData_SetLineupSelectIndex, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                SetLineupSelectIndex(player, buffer);
            }
        });

        //=======================================================================================================游戏关卡相关
        //客户端发送进入游戏关卡消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.GameLevel_Enter, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnGameLevelEnter(player, buffer);
            }
        });

        //客户端发送战斗胜利消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.GameLevel_Victory, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnGameLevelVictory(player, buffer);
            }
        });

        //客户端发送战斗失败消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.GameLevel_Fail, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnGameLevelFail(player, buffer);
            }
        });

        //客户端发送复活消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.GameLevel_Resurgence, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnGameLevelResurgence(player, buffer);
            }
        });

        //=======================================================================================================世界地图相关
        //客户端发送进入世界地图消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.WorldMap_RoleEnter, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnWorldMapEnter(player, buffer);
            }
        });

        //客户端发送世界地图上角色坐标
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.WorldMap_Pos, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnWorldMapPos(player, buffer);
            }
        });

        //======================================================任务相关
        //客户端发送查询任务消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Task_SearchTask, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnTaskSearchTask(player, buffer);
            }
        });

        //==================================================================商城背包
        //客户端发送购买商城物品消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Shop_BuyProduct, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnShopBuyProduct(player, buffer);
            }
        });

        //客户端发送查询背包项消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Backpack_Search, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnBackpackSearch(player, buffer);
            }
        });

        //客户端发送查询装备详情消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Goods_SearchEquipDetail, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnSearchEquipDetail(player, buffer);
            }
        });

        //客户端发送查询装备详情消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Goods_SellToSys, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnSellToSys(player, buffer);
            }
        });

        //客户端发送使用道具消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Goods_UseItem, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnUseItem(player, buffer);
            }
        });

        //客户端发送穿戴装备消息
        EventDispatcher.getInstance().AddEventListener(ProtoCodeDef.Goods_EquipPut, new OnActionHandler(){
            @Override
            public void dispatch(PlayerEntity player, byte[] buffer) throws IOException {
                OnEquipPut(player, buffer);
            }
        });
    }

    //============================系统相关

    /**
     * 客户端发送本地时间
     * @param playerEntity
     * @param buffer
     */
    private void OnSendLocalTime(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        System_SendLocalTimeProto proto = System_SendLocalTimeProto.GetProto(buffer);
        float localTime = proto.LocalTime;

        SystemServerTimeReturn(playerEntity, localTime);
        System_GameServerConfigReturn(playerEntity);
    }

    /**
     * 服务器返回服务器时间
     * @param playerEntity
     * @param localTime
     */
    private void SystemServerTimeReturn(PlayerEntity playerEntity, float localTime) throws IOException {
        System_ServerTimeReturnProto proto = new System_ServerTimeReturnProto();
        proto.LocalTime = localTime;
        proto.ServerTime = DateTime.now().getTime() / 10000;

        //给客户端发消息
        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /**
     * 服务器返回开关列表
     * @param playerEntity
     */
    private void System_GameServerConfigReturn(PlayerEntity playerEntity) throws IOException {
        System_GameServerConfigReturnProto proto = new System_GameServerConfigReturnProto();

        List<GameserverconfigDto> lst = gameserverconfigService.queryAll();
        if (lst != null)
        {
            proto.ConfigCount = lst.size();
            proto.ServerConfigList = new ArrayList<System_GameServerConfigReturnProto.ConfigItem>();
            for (int i = 0; i < lst.size(); i++)
            {
                int finalI = i;
                proto.ServerConfigList.add(new System_GameServerConfigReturnProto.ConfigItem()
                {{
                    ConfigCode = lst.get(finalI).getConfigCode();
                    IsOpen = lst.get(finalI).getIsOpen() == 1;
                    Param = lst.get(finalI).getParam();
                }});
            }
        }

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }


    //=========================================================登录相关

    /**
     * 客户端发送登录区服消息
     * @param player
     * @param buffer
     */
    private void OnLoginGameServer(PlayerEntity player, byte[] buffer) throws IOException {
        RoleOperation_LoginGameServerProto proto = RoleOperation_LoginGameServerProto.GetProto(buffer);

        //玩家帐号
        int accountId = proto.AccountId;
        int gameserverId = proto.GameServerId;

        player.accountId = accountId;
        player.gameserverId = gameserverId;
        LogOnGameServerReturn(player, accountId, gameserverId);
    }

    /**
     * 服务器返回登录区服消息
     * @param player
     * @param accountId
     */
    private void LogOnGameServerReturn(PlayerEntity player, int accountId, int gameserverId) throws IOException {
        RoleOperation_LoginGameServerReturnProto proto = new RoleOperation_LoginGameServerReturnProto();

        PlayerQueryCriteria criteria = new PlayerQueryCriteria();
        criteria.setAccountId(accountId);
        criteria.setGameserverId(gameserverId);

        List<PlayerDto> lst = playerService.queryAll(criteria);
        if (lst != null && lst.size() > 0)
        {
            proto.RoleCount = lst.size();
            proto.RoleList = new ArrayList<RoleOperation_LoginGameServerReturnProto.RoleItem>();

            for (int i = 0; i < lst.size(); i++)
            {
                RoleOperation_LoginGameServerReturnProto.RoleItem roleItem = new RoleOperation_LoginGameServerReturnProto.RoleItem();
                roleItem.RoleId = lst.get(i).getId();
                roleItem.RoleNickName = lst.get(i).getNickName();
                roleItem.RoleLevel = lst.get(i).getLevel();
                proto.RoleList.add(roleItem);
            }
        }
        else
        {
            proto.RoleCount = 0;
        }

        //给客户端发消息
        player.Client_Socket.SendMsg(proto.ToArray());
    }

    /**
     * 客户端发送创建角色消息
     * @param playerEntity
     * @param buffer
     * @throws IOException
     */
    private void OnCreatePlayer(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        RoleOperation_CreatePlayerProto proto = RoleOperation_CreatePlayerProto.GetProto(buffer);

        // 创建玩家信息并添加到数据库
        Player player = new Player();
        player.setNickName(proto.RoleNickName);
        player.setStatus(1);
        player.setLevel(1);
        player.setSex((int) proto.Sex);
        player.setMoney(0);
        player.setExp(0);
        player.setCurrLineupId(0);
        player.setCurrSelectLineupIndex(0);
        player.setLastInWorldMapId(0);
        player.setLastInWorldMapPos("");
        player.setAccountId(playerEntity.accountId);
        player.setGameserverId(playerEntity.gameserverId);
        PlayerDto playerDto = playerService.create(player);
        int playerId = playerDto.getId();

        // 创建角色信息并添加到数据库
        Role role = new Role();
        role.setStatus(1);
        role.setPlayerId(playerId);
        role.setRoleId(1);
        role.setName(playerDto.getNickName());
        role.setSex(playerDto.getSex());
        role.setLevel(1);
        role.setExp(0);
        role.setMaxHp(0);
        role.setMaxMp(0);
        role.setCurrHp(0);
        role.setCurrMp(0);
        role.setAttack(0);
        role.setDefense(0);
        role.setCri("0");
        role.setVioInjury("0");
        role.setRes(0);
        RoleDto roleDto = roleService.create(role);
        int roleId = roleDto.getId();

        // 创建阵容信息并添加到数据库
        Lineup lineup = new Lineup();
        lineup.setPlayerId(playerId);
        lineup.setName("阵容一");
        lineup.setRoleIds(""+roleId);
        LineupDto lineupDto = lineupService.create(lineup);
        int lineupId = lineupDto.getId();

        playerService.update(new Player() {{setId(playerId); setCurrLineupId(lineupId);}});

        playerDto = playerService.findById(playerId);
        if(playerDto != null) playerEntity.dtoToEntity(playerDto);

        OnCreateRoleReturn(playerEntity, lineupDto, roleDto);
    }

    /**
     * 服务器返回创建角色消息
     * @param playerEntity
     * @param lineupDto
     * @param roleDto
     * @throws IOException
     */
    private void OnCreateRoleReturn(PlayerEntity playerEntity, LineupDto lineupDto, RoleDto roleDto) throws IOException {
        RoleOperation_CreatePlayerReturnProto proto = new RoleOperation_CreatePlayerReturnProto();

        if (playerEntity.id != 0)
        {
            proto.IsSuccess = true;
        }
        else
        {
            proto.IsSuccess = false;
            proto.MessageId = 1000;
        }

        //给客户端发消息
        playerEntity.Client_Socket.SendMsg(proto.ToArray());

        if (proto.IsSuccess)
        {
            List<RoleDto> roleDtos = new ArrayList<>() {{
                add(roleDto);
            }};
            OnSelectPlayerInfoReturn(playerEntity);
            OnSelectLineupInfoReturn(playerEntity, lineupDto, roleDtos);
        }
    }

    /**
     * 客户端发送进入游戏消息
     * @param playerEntity
     * @param buffer
     * @throws IOException
     */
    private void OnEnterGame(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        RoleOperation_EnterGameProto proto = RoleOperation_EnterGameProto.GetProto(buffer);
        playerEntity.id = proto.PlayerId;
        OnEnterGameReturn(playerEntity);
    }

    /**
     * 服务器返回进入游戏消息
     * @param playerEntity
     * @throws IOException
     */
    private void OnEnterGameReturn(PlayerEntity playerEntity) throws IOException {
        RoleOperation_EnterGameReturnProto proto = new RoleOperation_EnterGameReturnProto();

        proto.IsSuccess = true;
        playerEntity.Client_Socket.SendMsg(proto.ToArray());

        PlayerDto playerDto = playerService.findById(playerEntity.id);
        playerEntity.dtoToEntity(playerDto);

        LineupDto lineupDto = lineupService.findById(playerEntity.currLineupId);

        List<RoleDto> roleDtos = roleService.findAllById(StringUtils.stringToIntegerList(lineupDto.getRoleIds(), ","));
        OnSelectPlayerInfoReturn(playerEntity);
        OnSelectLineupInfoReturn(playerEntity, lineupDto, roleDtos);

//        OnSkillReturn(role); //给客户端 发送技能信息
//
//        OnRechargeProductReturn(role); //给客户端发送 充值产品信息
    }

    /**
     * 服务器返回玩家信息
     * @param playerEntity
     */
    private void OnSelectPlayerInfoReturn(PlayerEntity playerEntity) throws IOException {
        RoleOperation_SelectRoleInfoReturnProto proto = new RoleOperation_SelectRoleInfoReturnProto();
        proto.IsSuccess = true;
        proto.Id = playerEntity.id;
        proto.NickName = playerEntity.nickName;
        proto.Status = playerEntity.status;
        proto.Level = playerEntity.level;
        proto.Sex = playerEntity.sex;
        proto.Money = playerEntity.money;
        proto.Exp = playerEntity.exp;
        proto.CurrLineupId = playerEntity.currLineupId;
        proto.CurrSelectLineupIndex = playerEntity.currSelectLineupIndex;
        proto.LastInWorldMapId = playerEntity.lastInWorldMapId;
        proto.LastInWorldMapPos = playerEntity.lastInWorldMapPos;

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /**
     * 服务器返回阵容信息
     */
    private void OnSelectLineupInfoReturn(PlayerEntity playerEntity, LineupDto lineupDto, List<RoleDto> roleDtos) throws IOException {
        RoleOperation_SelectLineupInfoReturnProto proto = new RoleOperation_SelectLineupInfoReturnProto();

        proto.Id = lineupDto.getId();
        proto.Name = lineupDto.getName();
        proto.PlayerId = lineupDto.getPlayerId();
        proto.RoleIds = lineupDto.getRoleIds();
        proto.RoleCount = roleDtos.size();
        proto.RoleList = new ArrayList<RoleOperation_SelectLineupInfoReturnProto.RoleItem>();
        for (int i = 0; i < roleDtos.size(); i++)
        {
            RoleOperation_SelectLineupInfoReturnProto.RoleItem _Role = new RoleOperation_SelectLineupInfoReturnProto.RoleItem();
            _Role.Id = roleDtos.get(i).getId();
            _Role.Status = roleDtos.get(i).getStatus();
            _Role.PlayerId = roleDtos.get(i).getPlayerId();
            _Role.RoleId = roleDtos.get(i).getRoleId();
            _Role.Name = roleDtos.get(i).getName();
            _Role.Sex = roleDtos.get(i).getSex();
            _Role.Level = roleDtos.get(i).getLevel();
            _Role.Exp =roleDtos.get(i).getExp();
            _Role.MaxHP = roleDtos.get(i).getMaxHp();
            _Role.MaxMP = roleDtos.get(i).getMaxMp();
            _Role.CurrHP = roleDtos.get(i).getCurrHp();
            _Role.CurrMP = roleDtos.get(i).getCurrMp();
            _Role.Attack = roleDtos.get(i).getAttack();
            _Role.Defense = roleDtos.get(i).getDefense();
            _Role.Cri = roleDtos.get(i).getCri();
            _Role.VioInjury = roleDtos.get(i).getVioInjury();
            _Role.Res = roleDtos.get(i).getRes();
            proto.RoleList.add(_Role);

            OnSkillReturn(playerEntity, _Role.Id);
        }

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }


    private void OnSkillReturn(PlayerEntity playerEntity, int roleId) throws IOException {
        RoleData_SkillReturnProto proto = new RoleData_SkillReturnProto();

        List<RoleSkillDto> lst = roleSkillService.queryAll(new RoleSkillQueryCriteria(){{setRoleId(roleId);}});
        if (lst != null)
        {
            proto.RoleId = roleId;
            proto.SkillCount = (byte)lst.size();
            proto.CurrSkillDataList = new ArrayList<RoleData_SkillReturnProto.SkillData>();

            for (int i = 0; i < lst.size(); i++)
            {
                int finalI = i;
                proto.CurrSkillDataList.add(new RoleData_SkillReturnProto.SkillData()
                {{
                    SkillId = lst.get(finalI).getSkillId();
                    SkillLevel = lst.get(finalI).getSkillLevel();
                    SlotsNo = (byte)(int)lst.get(finalI).getSlotsNo();
                }});
            }
            playerEntity.Client_Socket.SendMsg(proto.ToArray());
        }
    }

    private void SetLineupSelectIndex(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        RoleData_SetLineupSelectIndexProto proto = RoleData_SetLineupSelectIndexProto.GetProto(buffer);
        Player resources = new Player(){{setId(proto.PlayerId); setCurrSelectLineupIndex(proto.Index);}};
        playerService.update(resources);
        SetLineupSelectIndexReturn(playerEntity);
    }

    private void SetLineupSelectIndexReturn(PlayerEntity playerEntity) throws IOException {
        RoleData_SetLineupSelectIndexReturnProto proto = new RoleData_SetLineupSelectIndexReturnProto();
        PlayerDto playerDto = playerService.findById(playerEntity.id);
        playerEntity.currSelectLineupIndex = playerDto.getCurrSelectLineupIndex();
        proto.LineupId = playerEntity.currLineupId;
        proto.Index = playerEntity.currSelectLineupIndex;
        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    //===========================================================================游戏关卡相关

    /// <summary>
    /// 客户端发送进入游戏关卡消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnGameLevelEnter(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        //根据需要 验证体力 等信息
        GameLevel_EnterProto proto = GameLevel_EnterProto.GetProto(buffer);

        //添加攻打关卡记录
        LogGamelevel m_Log_GameLevel = new LogGamelevel();
        m_Log_GameLevel.setStatus(1);
        m_Log_GameLevel.setRoleId(playerEntity.id);
        m_Log_GameLevel.setGameLevelId(proto.GameLevelId);
        m_Log_GameLevel.setGrade((int) proto.Grade);
        m_Log_GameLevel.setAction(0);
        logGamelevelService.create(m_Log_GameLevel);

        //角色进入游戏关卡后，要离开世界地图
        worldMapSceneController.RoleLeave(playerEntity.id, playerEntity.PrevWorldMapId);

        GameLevel_EnterReturnProto retProto = new GameLevel_EnterReturnProto();
        retProto.IsSuccess = true;
        playerEntity.Client_Socket.SendMsg(retProto.ToArray());
    }

    /// <summary>
    /// 客户端发送战斗胜利消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnGameLevelVictory(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        GameLevel_VictoryProto proto = GameLevel_VictoryProto.GetProto(buffer);

        //1.添加或者修改玩家过关详情
        List<PlayerPassgameleveldetailDto> playerPassgameleveldetailDtos = playerPassgameleveldetailService.queryAll(new PlayerPassgameleveldetailQueryCriteria(){{
            setPlayerId(playerEntity.id);
            setGameLevelId(proto.GameLevelId);
        }});
        if (playerPassgameleveldetailDtos.size() > 0)
        {
            PlayerPassgameleveldetail resources = new PlayerPassgameleveldetail(){{
                setId(playerPassgameleveldetailDtos.get(0).getId());
                setPlayerId(playerEntity.id);
                setGameLevelId(proto.GameLevelId);
                setStar((int) proto.Star);
            }};
            playerPassgameleveldetailService.update(resources);
        }
        else
        {
            //添加
            PlayerPassgameleveldetail entity = new PlayerPassgameleveldetail(){{
                setStatus(1);
                setPlayerId(playerEntity.id);
                setGameLevelId(proto.GameLevelId);
                setGrade((int) proto.Grade);
                setStar((int) proto.Star);
                setIsMopUp(0);
            }};

            playerPassgameleveldetailService.create(entity);
        }

        //2.添加攻打关卡记录
        {
            LogGamelevel m_Log_GameLevel = new LogGamelevel(){{
                setStatus(1);
                setRoleId(playerEntity.id);
                setGameLevelId(proto.GameLevelId);
                setGrade((int) proto.Grade);
                setAction(1);
            }};
            logGamelevelService.create(m_Log_GameLevel);
        }

        //3.添加杀怪记录
        List<GameLevel_VictoryProto.MonsterItem> killMonsterList = proto.KillMonsterList;
        for (int i = 0; i < killMonsterList.size(); i++)
        {
            int finalI = i;
            LogKillmonster m_Log_KillMonster = new LogKillmonster(){{
                setStatus(1);
                setPlayerId(playerEntity.id);
                setPlayType(0);
                setPlaySceneId(proto.GameLevelId);
                setGrade((int)proto.Grade);
                setMonsterId(killMonsterList.get(finalI).MonsterId);
                setMonsterCount(killMonsterList.get(finalI).MonsterCount);
            }};

            logKillmonsterService.create(m_Log_KillMonster);
        }

        int goodsCount = proto.GoodsTotalCount;

        //4.添加获得物品记录
        List<GameLevel_VictoryProto.GoodsItem> getGoodsList = proto.GetGoodsList;

        //添加到背包的物品集合
        List<Role_BackpackAddItemEntity> lst = new ArrayList<Role_BackpackAddItemEntity>();

        for (int i = 0; i < getGoodsList.size(); i++)
        {
            int finalI1 = i;
            LogReceivegoods m_Log_ReceiveGoods = new LogReceivegoods(){{
                setStatus(1);
                setPlayerId(playerEntity.id);
                setPlayType(0);
                setPlaySceneId(proto.GameLevelId);
                setGrade((int) proto.Grade);
                setGoodsType((int) getGoodsList.get(finalI1).GoodsType);
                setGoodsId(getGoodsList.get(finalI1).GoodsId);
                setGoodsCount(getGoodsList.get(finalI1).GoodsCount);
            }};

            logReceivegoodsService.create(m_Log_ReceiveGoods);

            Role_BackpackAddItemEntity entity = null;

            //先查找集合中 是否已经有这个物品
            for (int j = 0; j < lst.size(); j++)
            {
                if ((lst.get(j).GoodsId == getGoodsList.get(i).GoodsId) && (lst.get(j).GoodsType == getGoodsList.get(i).GoodsType))
                {
                    entity = lst.get(i);
                    break;
                }
            }

            if (entity != null)
            {
                //如果有这个物品 则把物品的数量增加
                entity.GoodsCount += getGoodsList.get(i).GoodsCount;
            }
            else
            {
                //如果没有这个物品 则实例化新对象并赋值
                int finalI = i;
                entity = new Role_BackpackAddItemEntity()
                {{
                    GoodsType = getGoodsList.get(finalI).GoodsType;
                    GoodsId = getGoodsList.get(finalI).GoodsId;
                    GoodsCount = getGoodsList.get(finalI).GoodsCount;
                }};

                //然后加入列表
                lst.add(entity);
            }
        }

        List<Role_BackpackItemChangeEntity> changeList = null;
        //同时把这些物品 加入玩家的背包中
//        Role_BackpackCacheModel.Instance.Add(role.RoleId, GoodsInType.DropOut, lst, ref changeList);

        //5.给玩家添加经验和金币 设置最后通关的游戏关卡Id
        Player resources = new Player(){{
            setId(playerEntity.id);
            setExp(proto.Exp);
            setMoney(proto.Gold);
//            setLastPassGameLevelId(proto.GameLevelId);
        }};
        playerService.update(resources);

        GameLevel_VictoryReturnProto retProto = new GameLevel_VictoryReturnProto();
        retProto.IsSuccess = true;
        playerEntity.Client_Socket.SendMsg(retProto.ToArray());

        //给玩家发送物品更新消息
        OnGoodsChangeReturn(playerEntity, changeList);
    }

    /// <summary>
    /// 客户端发送战斗失败消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnGameLevelFail(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        //根据需要 验证体力 等信息
        GameLevel_FailProto proto = GameLevel_FailProto.GetProto(buffer);

        //添加攻打关卡记录
        LogGamelevel m_Log_GameLevel = new LogGamelevel(){{
            setStatus(1);
            setRoleId(playerEntity.id);
            setGameLevelId(proto.GameLevelId);
            setGrade((int) proto.Grade);
            setAction(2);
        }};

        GameLevel_FailReturnProto retProto = new GameLevel_FailReturnProto();
        retProto.IsSuccess = true;
        playerEntity.Client_Socket.SendMsg(retProto.ToArray());
    }

    /// <summary>
    /// 客户端发送复活消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnGameLevelResurgence(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        GameLevel_ResurgenceReturnProto retProto = new GameLevel_ResurgenceReturnProto();
        retProto.IsSuccess = true;
        playerEntity.Client_Socket.SendMsg(retProto.ToArray());
    }

    //========================================================世界地图相关

    /// 客户端发送进入世界地图消息
    private void OnWorldMapEnter(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        WorldMap_RoleEnterProto proto = WorldMap_RoleEnterProto.GetProto(buffer);
        playerEntity.lastInWorldMapId = proto.WorldMapSceneId;
        Player player = new Player(){{ setId(playerEntity.id);setLastInWorldMapId(playerEntity.lastInWorldMapId); setLastInWorldMapPos(null);}};
        playerService.update(player);

//        if (proto.WorldMapSceneId == 2)
//        {
//            playerEntity.CurrHP = playerEntity.MaxHP;
//            playerEntity.CurrMP = playerEntity.MaxMP;
//        }

        OnWorldMapEnterReturn(playerEntity);
    }

    /// 服务器返回角色进入世界地图
    private void OnWorldMapEnterReturn(PlayerEntity playerEntity) throws IOException {
        WorldMap_RoleEnterReturnProto proto = new WorldMap_RoleEnterReturnProto();
        proto.IsSuccess = true;
        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /// <summary>
    /// 客户端发送世界地图上角色坐标
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnWorldMapPos(PlayerEntity playerEntity, byte[] buffer)
    {
        WorldMap_PosProto proto = WorldMap_PosProto.GetProto(buffer);
        playerEntity.lastInWorldMapPos = String.format("%f_%f_%f_%f", proto.x, proto.y, proto.z, proto.yAngle);
        log.info(proto.x+"_"+proto.y+"_"+proto.z+"_"+proto.yAngle);
        log.info(playerEntity.lastInWorldMapPos);
        Player player = new Player(){{ setId(playerEntity.id);setLastInWorldMapPos(playerEntity.lastInWorldMapPos); }};
        playerService.update(player);
    }

    //========================================================================================任务相关
    /**
     *
     * @param playerEntity
     * @param buffer
     */
    private void OnTaskSearchTask(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        //测试环境，直接发给客户端伪数据

        Task_SearchTaskReturnProto proto = new Task_SearchTaskReturnProto();

        proto.CurrTaskItemList = new ArrayList<Task_SearchTaskReturnProto.TaskItem>();

        proto.CurrTaskItemList.add(new Task_SearchTaskReturnProto.TaskItem() {{Id = 1001; Name = "小试身手"; Status = 0; Content = "（服务器来的）我看少侠骨骼惊奇，天赋异禀，实在是个修仙的好料子，快去帮我去狼群杀死一些狼吧！";}});
        proto.CurrTaskItemList.add(new Task_SearchTaskReturnProto.TaskItem() {{ Id = 1002; Name = "武器考验"; Status = 1; Content = "好徒儿，现在的你仍然菜的很，这样吧，你去岐山西郊之地帮我对付几只小牛！！"; }});
        proto.CurrTaskItemList.add(new Task_SearchTaskReturnProto.TaskItem() {{ Id = 1003; Name = "技能传授"; Status = 2; Content = "玄兵斗法，阵列纲常。万法无极，心法合一！！"; }});
        proto.CurrTaskItemList.add(new Task_SearchTaskReturnProto.TaskItem() {{ Id = 1004; Name = "修为精进"; Status = 0; Content = "这事来的巧。前几日西郊频现异变蛇妖，这些妖蛇在附近村庄作祟，我派你前往除妖卫道，你可愿意？"; }});
        proto.CurrTaskItemList.add(new Task_SearchTaskReturnProto.TaskItem() {{ Id = 1005; Name = "强化武器"; Status = 1; Content = "徒儿，你可知磨刀不误砍柴工这个道理？你天赋异于常人，但仍需让你的武器和装备时时保持贴己趁手！"; }});
        proto.CurrTaskItemList.add(new Task_SearchTaskReturnProto.TaskItem() {{ Id = 1006; Name = "问路寻仙"; Status = 1; Content = "徒儿，问路寻仙了！"; }});


        proto.TaskCount = proto.CurrTaskItemList.size();
        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    //============================================================================================商城背包
    /// <summary>
    /// 客户端发送购买商城物品消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnShopBuyProduct(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        Shop_BuyProductProto proto = Shop_BuyProductProto.GetProto(buffer);
        OnShopBuyProductReturn(playerEntity, proto.ProductId);
    }

    /// <summary>
    /// 服务器返回购买商城物品消息
    /// </summary>
    /// <param name="role"></param>
    private void OnShopBuyProductReturn(PlayerEntity playerEntity, int productId) throws IOException {
        Boolean hasError = false;
        int msgCode = 102009;
        int oldMoney = playerEntity.money; //原始元宝

        //1.查询玩家要购买的商品是否存在 如果商品不存在 提示 购买失败 您选择的商品不存在
        //这个productId 就是Shop表中的Id 所以这里就是查询的Shop表
        ShopEntity entity = ShopDBModel.getInstance().Get(productId);
        if (entity == null)
        {
            hasError = true;
            msgCode = 102007;
        }

        //2.查询玩家拥有的元宝 是否足够支持这个商品 如果不够 提示 购买失败 您的元宝不足 请先充值
        if (!hasError)
        {
            if (entity.Price > playerEntity.money) //如果这个商品价格 超过玩家拥有的元宝
            {
                hasError = true;
                msgCode = 102008;
            }
        }

        //3.扣除玩家身上的元宝 并添加购买日志
        if (!hasError)
        {
            //减掉玩家对象上的元宝
            playerEntity.money -= entity.Price;

            //减掉数据库中 玩家的元宝
            Player resources = new Player(){{
                setId(playerEntity.id);
                setMoney(playerEntity.money);
            }};
            playerService.update(resources);

            //添加购买日志
            LogShopbuyproduct logEntity = new LogShopbuyproduct(){{
                setStatus(1);
                setPlayerId(playerEntity.id);
                setShopId(productId);
                setGoodsType(entity.GoodsType);
                setShopId(entity.GoodsId);
                setGoodsCount(1);
            }};
            logShopbuyproductService.create(logEntity);
        }

        List<Role_BackpackItemChangeEntity> changeList = null;

        //4.给玩家的背包中添加购买到的物品
        if (!hasError)
        {
            changeList = playerBackpackService.add(playerEntity.id, GoodsInType.ShopBuy, new Role_BackpackAddItemEntity()
            {{
                GoodsType = (byte)(int)entity.GoodsType;
                GoodsId = entity.GoodsId;
                GoodsCount = 1;
            }});
        }

        Shop_BuyProductReturnProto proto = new Shop_BuyProductReturnProto();
        proto.IsSuccess = !hasError;
        proto.MsgCode = msgCode;
        playerEntity.Client_Socket.SendMsg(proto.ToArray());

        //5.给玩家发送元宝更新消息
        if (!hasError)
        {
            OnMondeyChangeReturn(playerEntity, oldMoney, playerEntity.money, ChangeType.Reduce.hashCode(), MoneyAddType.None.ordinal(), MoneyReduceType.BuyShopProduct.ordinal(), entity.GoodsType, entity.GoodsId);
        }

        //6.给玩家发送物品更新消息
        if (!hasError)
        {
            OnGoodsChangeReturn(playerEntity, changeList);
        }
    }

    /// <summary>
    /// 客户端发送查询背包项消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnBackpackSearch(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        OnBackpackSearchReturn(playerEntity);
    }

    /// <summary>
    /// 服务器返回查询背包项消息
    /// </summary>
    private void OnBackpackSearchReturn(PlayerEntity playerEntity) throws IOException {

        Backpack_SearchReturnProto proto = new Backpack_SearchReturnProto();

        //查询玩家的背包项
        List<PlayerBackpackDto> lst = playerBackpackService.queryAll(new PlayerBackpackQueryCriteria(){{
            setPlayerId(playerEntity.id);
        }});

        proto.BackpackItemCount = lst.size();
        proto.ItemList = new ArrayList<Backpack_SearchReturnProto.BackpackItem>();

        for (int i = 0; i < lst.size(); i++)
        {
            int finalI = i;
            proto.ItemList.add(new Backpack_SearchReturnProto.BackpackItem()
            {{
                BackpackItemId = lst.get(finalI).getId();
                GoodsType = (byte)(int)lst.get(finalI).getGoodsType();
                GoodsId = lst.get(finalI).getGoodsId();
                GoodsServerId = lst.get(finalI).getGoodsServerId();
                GoodsOverlayCount = lst.get(finalI).getGoodsOverlayCount();
            }});
        }

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /// <summary>
    /// 客户端发送查询装备详情消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnSearchEquipDetail(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        Goods_SearchEquipDetailProto proto = Goods_SearchEquipDetailProto.GetProto(buffer);
        OnSearchEquipDetailReturn(playerEntity, proto.GoodsServerId);
    }

    /// <summary>
    /// 服务器返回查询装备详情消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="goodsServerId"></param>
    private void OnSearchEquipDetailReturn(PlayerEntity playerEntity, int goodsServerId) throws IOException {
        Goods_SearchEquipDetailReturnProto proto = new Goods_SearchEquipDetailReturnProto();

        PlayerEquipDto entity = playerEquipService.findById(goodsServerId);
        proto.EnchantLevel = entity.getEnchantLevel();
        proto.BaseAttr1Type = (byte)(int)entity.getBaseAttr1Type();
        proto.BaseAttr1Value = entity.getBaseAttr1Value();
        proto.BaseAttr2Type = (byte)(int)entity.getBaseAttr2Type();
        proto.BaseAttr2Value = entity.getBaseAttr2Value();
        proto.HP = entity.getHp();
        proto.MP = entity.getMp();
        proto.Attack = entity.getAttack();
        proto.Defense = entity.getDefense();
        proto.Hit = entity.getHit();
        proto.Dodge = entity.getDodge();
        proto.Cri = entity.getCri();
        proto.Res = entity.getRes();
        proto.IsPutOn = (byte)(int)entity.getIsPutOn();

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /// <summary>
    /// 客户端发送出售物品给系统
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnSellToSys(PlayerEntity playerEntity, byte[] buffer)
    {
//        Goods_SellToSysProto proto = Goods_SellToSysProto.GetProto(buffer);
//
//        //执行出售物品的操作
//        MFReturnValue<bool> retValue = playerBackpackService.sellToSys(playerEntity.id, proto.roleBackpackId, (int)proto.GoodsType, proto.GoodsId, proto.GoodsServerId, proto.SellCount);
//
//        if (!retValue.HasError)
//        {
//            List<Role_BackpackItemChangeEntity> lst = retValue.GetOutputValue<List<Role_BackpackItemChangeEntity>>("BackpackItemChange");
//
//            OnGoodsChangeReturn(role, lst);
//
//            //总售价
//            int totalSellPrice = retValue.GetOutputValue<int>("TotalSellPrice");
//
//            //更新玩家身上的金币数量
//            RoleEntity entity = RoleCacheModel.Instance.GetEntity(role.RoleId);
//
//            int oldGold = entity.Gold; //旧的金币
//            int currGold = oldGold + totalSellPrice;
//
//            Dictionary<string, object> param = new Dictionary<string, object>();
//            param["@Id"] = role.RoleId;
//            param["@Gold"] = currGold;
//
//            RoleCacheModel.Instance.Update("[Gold]= @Gold", "Id=@Id", param); //更新数据库
//
//            OnGoldChangeReturn(role, oldGold, currGold, ChangeType.Add, GoldAddType.GoodsSell, GoldReduceType.BubGoods, (GoodsType)proto.GoodsType, proto.GoodsId);
//        }
//        else
//        {
//            Console.WriteLine(retValue.Error.Message);
//        }
    }

    /// <summary>
    /// 客户端发送使用道具消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnUseItem(PlayerEntity playerEntity, byte[] buffer) throws IOException {
//        Goods_UseItemProto proto = Goods_UseItemProto.GetProto(buffer);
//
//        MFReturnValue<bool> retValue = playerBackpackService.useItem(playerEntity.id, proto.BackpackItemId, proto.GoodsId);
//
//        if (!retValue.HasError)
//        {
//            //得到物品更新列表 但是这个列表只是物品减少的 就是刚才使用的道具消失
//            List<Role_BackpackItemChangeEntity> lst = retValue.GetOutputValue<List<Role_BackpackItemChangeEntity>>("BackpackItemChange");
//
//            //发送物品更新消息
//            OnGoodsChangeReturn(playerEntity, lst);
//
//            //虚拟资产更新列表 指的是不进入背包的 非物品更新
//            List<VirtualItemUpdateEntity> virtualItemUpdateList = retValue.GetOutputValue<List<VirtualItemUpdateEntity>>("VirtualItemUpdateList");
//
//            for (int i = 0; i < virtualItemUpdateList.size(); i++)
//            {
//                VirtualItemUpdateEntity entity = virtualItemUpdateList[i];
//
//                if (entity.Type == ItemUsedAcquisitionType.Money)
//                {
//                    //发送元宝更新消息
//                    OnMondeyChangeReturn(playerEntity, entity.OldValue, entity.CurrValue, entity.ChangeType,
//                            MoneyAddType.ItemUsed.ordinal(), MoneyReduceType.None.ordinal(), GoodsType.Item.ordinal(), proto.GoodsId);
//                }
//                else if (entity.Type == ItemUsedAcquisitionType.Gold)
//                {
//                    //发送金币更新消息
//                    OnGoldChangeReturn(playerEntity, entity.OldValue, entity.CurrValue, entity.ChangeType,
//                            GoldAddType.ItemUsed.ordinal(), GoldReduceType.None.ordinal(), GoodsType.Item.ordinal(), proto.GoodsId);
//                }
//                else if (entity.Type == ItemUsedAcquisitionType.Exp)
//                {
//                    //发送经验更新消息
//                    //检查是否可以升级 如果可以升级 发送升级消息
//                }
//            }
//
//            OnUseItemRetrun(playerEntity, true, 0, proto.GoodsId);
//        }
//        else
//        {
//            OnUseItemRetrun(playerEntity, false, retValue.ReturnCode, proto.GoodsId);
//        }
    }

    /// <summary>
    ///  服务器返回道具使用消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="isSuccess"></param>
    /// <param name="msgCode"></param>
    /// <param name="goodsId"></param>
    private void OnUseItemRetrun(PlayerEntity playerEntity, Boolean isSuccess, Integer msgCode, Integer goodsId) throws IOException {

        Goods_UseItemReturnProto proto = new Goods_UseItemReturnProto();
        proto.IsSuccess = isSuccess;
        proto.MsgCode = msgCode;
        proto.GoodsId = goodsId;

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /// <summary>
    /// 客户端发送穿戴装备消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="buffer"></param>
    private void OnEquipPut(PlayerEntity playerEntity, byte[] buffer) throws IOException {
        Goods_EquipPutProto proto = Goods_EquipPutProto.GetProto(buffer);

        if (proto.Type == 0)
        {
            //穿上
            List<Role_BackpackItemChangeEntity> lst = new ArrayList<Role_BackpackItemChangeEntity>();
//            RoleCacheModel.Instance.EquipPutOn(role.RoleId, proto.GoodsId, proto.GoodsServerId, ref lst);

            //发送物品更新消息
            OnGoodsChangeReturn(playerEntity, lst);

//            //发送角色信息更新消息
//            OnSelectRoleInfoReturn(playerEntity);
        }
        else
        {
            //脱下
            List<Role_BackpackItemChangeEntity> lst = new ArrayList<Role_BackpackItemChangeEntity>();
//            RoleCacheModel.Instance.EquipPutOff(role.RoleId, proto.GoodsId, proto.GoodsServerId, ref lst);

            //发送物品更新消息
            OnGoodsChangeReturn(playerEntity, lst);

//            //发送角色信息更新消息
//            OnSelectRoleInfoReturn(playerEntity);
        }
    }

    //===================================================================各种更新消息
    /// <summary>
    /// 发送元宝更新消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="oldMoney">更新前元宝</param>
    /// <param name="currMoney">更新后当前元宝</param>
    /// <param name="changeType">更新方式 0=增加 1=减少</param>
    /// <param name="addType">增加方式 1=充值 2=使用元宝票 3=系统奖励 4=GM奖励或补偿</param>
    /// <param name="reduceType">减少方式 1=购买商城物品 2=兑换成元宝票 3=原地复活</param>
    /// <param name="goodsType">物品类型 0=装备 1=道具 2=材料</param>
    /// <param name="goodsId">物品编号</param>
    private void OnMondeyChangeReturn(PlayerEntity playerEntity, int oldMoney, int currMoney, int changeType, int addType, int reduceType, int goodsType, int goodsId) throws IOException {
        RoleData_MondeyChangeReturnProto proto = new RoleData_MondeyChangeReturnProto();
        proto.OldMoney = oldMoney;
        proto.CurrMoney = currMoney;
        proto.ChangeType = (byte)changeType;
        proto.AddType = (byte)addType;
        proto.ReduceType = (byte)reduceType;
        proto.GoodsType = (byte)goodsType;
        proto.GoodsId = goodsId;

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /// <summary>
    /// 服务器返回金币更新消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="oldGold"></param>
    /// <param name="currGold"></param>
    /// <param name="changeType"></param>
    /// <param name="goldAddType"></param>
    /// <param name="goldReduceType"></param>
    /// <param name="goodsType"></param>
    /// <param name="goodsId"></param>
    private void OnGoldChangeReturn(PlayerEntity playerEntity, int oldGold, int currGold, int changeType,
                                    int goldAddType, int goldReduceType, int goodsType, int goodsId) throws IOException {
        RoleData_GoldChangeReturnProto proto = new RoleData_GoldChangeReturnProto();
        proto.OldGold = oldGold;
        proto.CurrGold = currGold;
        proto.ChangeType = (byte)changeType;
        proto.AddType = (byte)goldAddType;
        proto.ReduceType = (byte)goldReduceType;
        proto.GoodsType = (byte)goodsType;
        proto.GoodsId = goodsId;

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }

    /// <summary>
    /// 服务器发送背包项更新消息
    /// </summary>
    /// <param name="role"></param>
    /// <param name="lst"></param>
    private void OnGoodsChangeReturn(PlayerEntity playerEntity, List<Role_BackpackItemChangeEntity> lst) throws IOException {
        //把更新消息 发给客户端
        Backpack_GoodsChangeReturnProto proto = new Backpack_GoodsChangeReturnProto();

        proto.BackpackItemChangeCount = lst.size();
        proto.ItemList = new ArrayList<Backpack_GoodsChangeReturnProto.ChangeItem>();

        //Console.WriteLine("服务器发送背包项更新消息==>>" + proto.BackpackItemChangeCount.ToString());

        for (int i = 0; i < lst.size(); i++)
        {
            Role_BackpackItemChangeEntity entity = lst.get(i);

            proto.ItemList.add(new Backpack_GoodsChangeReturnProto.ChangeItem()
            {{
                BackpackId = entity.BackpackId;
                ChangeType = entity.Type;
                GoodsType = entity.GoodsType;
                GoodsId = entity.GoodsId;
                GoodsCount = entity.GoodsCount;
                GoodsServerId = entity.GoodsServerId;
            }});
        }

        playerEntity.Client_Socket.SendMsg(proto.ToArray());
    }
}
